static gboolean is_gdm_mode = FALSE;
static char *session_mode = NULL;
+static int caught_signal = 0;
#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1
#define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4
enum {
SHELL_DEBUG_BACKTRACE_WARNINGS = 1,
+ SHELL_DEBUG_BACKTRACE_SEGFAULTS = 2,
};
static int _shell_debug;
shell_init_debug (const char *debug_env)
{
static const GDebugKey keys[] = {
- { "backtrace-warnings", SHELL_DEBUG_BACKTRACE_WARNINGS }
+ { "backtrace-warnings", SHELL_DEBUG_BACKTRACE_WARNINGS },
+ { "backtrace-segfaults", SHELL_DEBUG_BACKTRACE_SEGFAULTS },
};
_shell_debug = g_parse_debug_string (debug_env, keys,
{
}
+static void
+dump_gjs_stack_alarm_sigaction (int signo,
+ siginfo_t *info,
+ void *data)
+{
+ g_warning ("Failed to dump Javascript stack, got stuck");
+
+ raise (caught_signal);
+}
+
+static void
+dump_gjs_stack_on_signal_handler (int signo)
+{
+ /* Waiting at least 5 seconds for the dumpstack, if it fails, we raise the error */
+ struct sigaction sa;
+
+ caught_signal = signo;
+ memset (&sa, 0, sizeof (sigaction));
+ sigemptyset (&sa.sa_mask);
+
+ sa.sa_flags = SA_SIGINFO;
+ sa.sa_sigaction = dump_gjs_stack_alarm_sigaction;
+
+ sigaction (SIGALRM, &sa, NULL);
+
+ alarm (5);
+ gjs_dumpstack ();
+ alarm (0);
+
+ raise (signo);
+}
+
+static void
+dump_gjs_stack_on_signal (int signo)
+{
+ struct sigaction sa;
+
+ memset (&sa, 0, sizeof (sigaction));
+ sigemptyset (&sa.sa_mask);
+
+ sa.sa_flags = SA_RESETHAND;
+ sa.sa_handler = dump_gjs_stack_on_signal_handler;
+
+ sigaction (signo, &sa, NULL);
+}
+
static gboolean
list_modes (const char *option_name,
const char *value,
shell_prefs_init ();
+ dump_gjs_stack_on_signal (SIGABRT);
+ dump_gjs_stack_on_signal (SIGFPE);
+ dump_gjs_stack_on_signal (SIGIOT);
+ dump_gjs_stack_on_signal (SIGTRAP);
+
+ if ((_shell_debug & SHELL_DEBUG_BACKTRACE_SEGFAULTS))
+ {
+ dump_gjs_stack_on_signal (SIGBUS);
+ dump_gjs_stack_on_signal (SIGSEGV);
+ }
+
ecode = meta_run ();
g_debug ("Doing final cleanup");